﻿using System;
using System.Collections.Generic;

using System.Text;
using System.Runtime.InteropServices;

namespace MSL.Utility.Device
{
    /// <summary>
    /// 计算机重启、关电源、注销、关闭显示器辅助类
    /// </summary>
    public class Sys
    {
        private static Microsoft.Win32.RegistryKey regist =
            Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);


        #region 辅助函数
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        internal struct TokPriv1Luid
        {
            public Int32 Count;
            public long Luid;
            public Int32 Attr;
        }

        [DllImport("kernel32.dll", ExactSpelling = true)]
        internal static extern IntPtr GetCurrentProcess();

        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool OpenProcessToken(IntPtr h, int acc, ref   IntPtr phtok);

        [DllImport("advapi32.dll", SetLastError = true)]
        internal static extern bool LookupPrivilegeValue(string host, string name, ref   long pluid);

        [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
        ref   TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);

        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        internal static extern bool ExitWindowsEx(int flg, int rea);

        internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
        internal const int TOKEN_QUERY = 0x00000008;
        internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
        internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
        internal const int EWX_LOGOFF = 0x00000000;
        internal const int EWX_SHUTDOWN = 0x00000001;
        internal const int EWX_REBOOT = 0x00000002;
        internal const int EWX_FORCE = 0x00000004;
        internal const int EWX_POWEROFF = 0x00000008;
        internal const int EWX_FORCEIFHUNG = 0x00000010;

        #endregion

        #region 自动启动

        /// <summary>
        /// 取消自动启动
        /// </summary>
        /// <param name="appName">软件名称</param>
        /// <param name="shouldRun">设置/取消自动启动</param>
        public static void AutoStartup(string appName, bool shouldRun)
        {
            if (new API.Regedit().Exist(appName))
            {
                AutoStartup(appName, shouldRun, Environment.CommandLine);
            }
        }

        /// <summary>
        /// 系统设置/取消自动启动
        /// </summary>
        /// <param name="appName">软件名称</param>
        /// <param name="shouldRun">是否自动启动</param>
        /// <param name="exePath">系统执行路径（可增加配置参数）</param>
        public static void AutoStartup(string appName, bool shouldRun, string exePath)
        {
            if (shouldRun)
            {
                regist.SetValue(appName, exePath);
            }
            else
            {
                regist.DeleteValue(appName, false);
            }
        }
        #endregion

        #region 操作系统

        private static int Instr(string strA, string strB)
        {
            if (string.Compare(strA, strA.Replace(strB, "")) > 0)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
        /// <summary>
        /// 判断客户端操作系统和浏览器的配置
        /// </summary>
        /// <param name="info">客户端返回的头信息(Request.UserAgent)</param>
        /// <param name="type">获取类型：1为操作系统， 2为浏览器</param>
        /// <returns></returns>
        public static string SystemInfo(string info, int type)
        {
            string GetInfo = "";
            switch (type)
            {
                case 1:
                    if (Instr(info, @"NT 5.1") > 0)
                    {
                        GetInfo = "操作系统：Windows XP";
                    }
                    else if (Instr(info, @"Tel") > 0)
                    {
                        GetInfo = "操作系统：Telport";
                    }
                    else if (Instr(info, @"webzip") > 0)
                    {
                        GetInfo = "操作系统：操作系统：webzip";
                    }
                    else if (Instr(info, @"flashget") > 0)
                    {
                        GetInfo = "操作系统：flashget";
                    }
                    else if (Instr(info, @"offline") > 0)
                    {
                        GetInfo = "操作系统：offline";
                    }
                    else if (Instr(info, @"NT 5") > 0)
                    {
                        GetInfo = "操作系统：Windows 2000";
                    }
                    else if (Instr(info, @"NT 4") > 0)
                    {
                        GetInfo = "操作系统：Windows NT4";
                    }
                    else if (Instr(info, @"98") > 0)
                    {
                        GetInfo = "操作系统：Windows 98";
                    }
                    else if (Instr(info, @"95") > 0)
                    {
                        GetInfo = "操作系统：Windows 95";
                    }
                    else
                    {
                        GetInfo = "操作系统：未知";
                    }
                    break;
                case 2:
                    if (Instr(info, @"NetCaptor 6.5.0") > 0)
                    {
                        GetInfo = "浏 览 器：NetCaptor 6.5.0";
                    }
                    else if (Instr(info, @"MyIe 3.1") > 0)
                    {
                        GetInfo = "浏 览 器：MyIe 3.1";
                    }
                    else if (Instr(info, @"NetCaptor 6.5.0RC1") > 0)
                    {
                        GetInfo = "浏 览 器：NetCaptor 6.5.0RC1";
                    }
                    else if (Instr(info, @"NetCaptor 6.5.PB1") > 0)
                    {
                        GetInfo = "浏 览 器：NetCaptor 6.5.PB1";
                    }
                    else if (Instr(info, @"MSIE 6.0b") > 0)
                    {
                        GetInfo = "浏 览 器：Internet Explorer 6.0b";
                    }
                    else if (Instr(info, @"MSIE 6.0") > 0)
                    {
                        GetInfo = "浏 览 器：Internet Explorer 6.0";
                    }
                    else if (Instr(info, @"MSIE 5.5") > 0)
                    {
                        GetInfo = "浏 览 器：Internet Explorer 5.5";
                    }
                    else if (Instr(info, @"MSIE 5.01") > 0)
                    {
                        GetInfo = "浏 览 器：Internet Explorer 5.01";
                    }
                    else if (Instr(info, @"MSIE 5.0") > 0)
                    {
                        GetInfo = "浏 览 器：Internet Explorer 5.0";
                    }
                    else if (Instr(info, @"MSIE 4.0") > 0)
                    {
                        GetInfo = "浏 览 器：Internet Explorer 4.0";
                    }
                    else
                    {
                        GetInfo = "浏 览 器：未知";
                    }
                    break;
            }
            return GetInfo;
        }
        #endregion

        #region 打开系统记事本

        [DllImport("User32.DLL")]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, string lParam);

        [DllImport("User32.DLL")]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
        public const uint WM_SETTEXT = 0x000C;
        public static System.Diagnostics.Process proc = new System.Diagnostics.Process();
        /// <summary>
        /// 打开系统进程
        /// </summary>
        /// <param name="processName">外部程序名 如：记事本用 notepad.exe 计算器用 calc.exe</param>
        public static void OpenSystemProcess(string processName)
        {
            if (String.IsNullOrEmpty(processName))
            {
                return;
            }
            System.Diagnostics.ProcessStartInfo proccessInfo = new System.Diagnostics.ProcessStartInfo();
            proccessInfo.FileName = processName;
            //设置启动参数
            proccessInfo.Arguments = "";
            //设置程序工作目录为c:\windows
            proccessInfo.WorkingDirectory = "c:/windows/";

            try
            {
                // 
                //启动外部程序 
                // 
                proc = System.Diagnostics.Process.Start(proccessInfo);
            }
            catch
            {
                //MessageBox.Show("系统找不到指定的程序文件", "错误提示！");
                return;
            }
        }
        #endregion

        #region 计算机重启/关机/注销

        /// <summary>
        /// 计算机重启
        /// </summary>
        public static void Reboot()
        {
            DoExitWin(EWX_FORCE | EWX_REBOOT);
        }

        /// <summary>
        /// 计算机关电源
        /// </summary>
        public static void PowerOff()
        {
            DoExitWin(EWX_FORCE | EWX_POWEROFF);
        }

        /// <summary>
        /// 计算机注销
        /// </summary>
        public static void LogoOff()
        {
            DoExitWin(EWX_FORCE | EWX_LOGOFF);
        }
        #endregion

        #region 显示器打开/关闭
        private const uint WM_SYSCOMMAND = 0x0112;
        private const uint SC_MONITORPOWER = 0xF170;
        private static readonly IntPtr HWND_HANDLE = new IntPtr(0xffff);
        [DllImport("user32")]
        public static extern IntPtr SendMessage(IntPtr hWnd, uint wMsg, uint wParam, int lParam);

        /// <summary>
        /// 打开显示器
        /// </summary>
        public static void OpenMonitor()
        {
            // 2 为关闭显示器， －1则打开显示器
            SendMessage(HWND_HANDLE, WM_SYSCOMMAND, SC_MONITORPOWER, -1);
        }
        /// <summary>
        /// 关闭显示器
        /// </summary>
        public static void CloseMonitor()
        {
            // 2 为关闭显示器， －1则打开显示器
            SendMessage(HWND_HANDLE, WM_SYSCOMMAND, SC_MONITORPOWER, 2);
        }

        #endregion

        #region 私有方法

        private static void DoExitWin(int flg)
        {
            bool ok;
            TokPriv1Luid tp;
            IntPtr hproc = GetCurrentProcess();
            IntPtr htok = IntPtr.Zero;
            ok = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref   htok);
            tp.Count = 1;
            tp.Luid = 0;
            tp.Attr = SE_PRIVILEGE_ENABLED;
            ok = LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref   tp.Luid);
            ok = AdjustTokenPrivileges(htok, false, ref   tp, 0, IntPtr.Zero, IntPtr.Zero);
            ok = ExitWindowsEx(flg, 0);
        }
        #endregion
    }
}
